﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.IO;
using System.IO.Ports;
using System.Threading;
using SerialPortHelperLib;
using System.Text.RegularExpressions;

namespace XChipTool
{
    public partial class XChip_GroupWrite : DevExpress.XtraEditors.XtraForm
    {
        public SerialPort sPortTemp;
        public static UInt32 addr;//全局变量
                                  // 定义一个静态变量来保存类的实例
        private static XChip_GroupWrite _xchip_GroupWrite;
        // 定义一个标识确保线程同步
        private static readonly object locker = new object();
        public XChip_GroupWrite()
        {
            InitializeComponent();
        }
        public XChip_GroupWrite(SerialPort _sPortTemp)
        {
            sPortTemp = _sPortTemp;
            InitializeComponent();
        }
        public static XChip_GroupWrite GetInstance(SerialPort _sPortTemp)
        {
            // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
            // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (_xchip_GroupWrite == null || _xchip_GroupWrite.IsDisposed)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建，否则直接返回
                    if (_xchip_GroupWrite == null || _xchip_GroupWrite.IsDisposed)
                    {
                        _xchip_GroupWrite = new XChip_GroupWrite(_sPortTemp);
                    }
                }
            }
            return _xchip_GroupWrite;
        }
        //无参的
        public static XChip_GroupWrite GetInstance()
        {
            // 当第一个线程运行到这里时，此时会对locker对象 "加锁"，
            // 当第二个线程运行该方法时，首先检测到locker对象为"加锁"状态，该线程就会挂起等待第一个线程解锁
            // lock语句运行完之后（即线程运行完之后）会对该对象"解锁"
            // 双重锁定只需要一句判断就可以了
            if (_xchip_GroupWrite == null || _xchip_GroupWrite.IsDisposed)
            {
                lock (locker)
                {
                    // 如果类的实例不存在则创建，否则直接返回
                    if (_xchip_GroupWrite == null || _xchip_GroupWrite.IsDisposed)
                    {
                        _xchip_GroupWrite = new XChip_GroupWrite();
                    }
                }
            }
            return _xchip_GroupWrite;
        }
        private void btn_SensorFileWrite_Click(object sender, EventArgs e)
        {
            if (!sPortTemp.IsOpen)//串口检测
            {
                DevExpress.XtraEditors.XtraMessageBox.Show("串口未打开");
                return;
            }
            List<string> listRecording = new List<string>();
            if (radioGroup1.SelectedIndex != 0 && radioGroup1.SelectedIndex != 1)
            {
                if (string.IsNullOrEmpty(I2C_ID.Text))
                {
                    DevExpress.XtraEditors.XtraMessageBox.Show("请输入I2C_ID");
                    return;
                }
                SerialSend.WriteRegister(0x20000046, (uint)Convert.ToUInt32(I2C_ID.Text, 16), sPortTemp);
                listRecording.Add($"0x20000046,0x{(Convert.ToUInt32(I2C_ID.Text, 16)).ToString("X2")}");
            }
            OpenFileDialog openFileDialog1 = new OpenFileDialog();//将打开的地址给ofd
            openFileDialog1.Filter = "TXT Files(*.txt)|*.txt|All Files(*.*)|*.*";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)//用户是否选择确定
            {
                SerialSend.WriteRegister(0x20000048, (uint)Convert.ToUInt32(sensor_reg.Text, 16)  & 0xff, sPortTemp);
                SerialSend.WriteRegister(0x20000049, (uint)Convert.ToUInt32(sensor_reg.Text, 16) >> 8  & 0xff, sPortTemp);
                SerialSend.WriteRegister(0x2000004a, (uint)Convert.ToUInt32(sensor_reg.Text, 16) >> 16 & 0xff, sPortTemp);
                SerialSend.WriteRegister(0x2000004b, (uint)Convert.ToUInt32(sensor_reg.Text, 16) >> 24 & 0xff, sPortTemp);
                
                listRecording.Add($"0x20000048,0x{(Convert.ToUInt32(sensor_reg.Text, 16) & 0xff).ToString("X2")}");
                listRecording.Add($"0x20000049,0x{(Convert.ToUInt32(sensor_reg.Text, 16) >> 8  & 0xff).ToString("X2")}");
                listRecording.Add($"0x2000004a,0x{(Convert.ToUInt32(sensor_reg.Text, 16) >> 16 & 0xff).ToString("X2")}");
                listRecording.Add($"0x2000004b,0x{(Convert.ToUInt32(sensor_reg.Text, 16) >> 24 & 0xff).ToString("X2")}");
                SerialSend.WriteRegister(0x20000045, Convert.ToUInt32(radioGroup1.SelectedIndex.ToString(),16), sPortTemp);
                listRecording.Add($"0x20000045,0x{Convert.ToUInt32(radioGroup1.SelectedIndex).ToString("X2")}");
                try
                {
                    int addrCount = 0;
                    var result = ReadTextFileToList(openFileDialog1.FileName);
                    string fffevalue = "";
                    List<string> listR = new List<string>();
                    foreach (var item in result)
                    {
                        if (!string.IsNullOrEmpty(item))
                        {
                            if ((item.Length >= 2 && item.Substring(0, 2).Contains("0x")))
                            {
                                if (item.Contains("0xfff2")|| item.Contains("0xfffe") || item.Contains("0xfffd") || item.Contains("0xfff8"))
                                {
                                    if (item.Contains("0xfffe"))
                                    {
                                        fffevalue = item.Split(',')[1].Replace("0x", "");
                                    }
                                    continue;
                                }
                                List<string> listReg = new List<string>();
                                if (radioGroup1.SelectedIndex == 0)
                                {
                                    listReg.Add(item.ToString().Replace("0x", "").Replace(" ", "").Replace("，", ",").ToLower().Split(',')[0]);
                                    listReg.Add(item.ToString().Replace("0x", "").Replace(" ", "").Replace("，", ",").ToLower().Split(',')[1]);
                                }
                                else
                                {
                                    listReg = Regex16ToString(item);
                                }
                                if (listReg.Count >= 2)
                                {
                                    listR.Add(listReg[0]+ "," + listReg[1]);
                                }
                            }
                        }
                    }
                    List<string> listvalue = new List<string>();
                    switch (radioGroup1.SelectedIndex)
                    {
                        case 0:
                            
                            for (int i = 0; i < listR.Count(); i++)
                            {
                                var listSplit = string.Join("",listR[i].Split(','));

                                for (int j = 0; j < listSplit.Length; j++)
                                {
                                    listvalue.Add(listSplit[j].ToString() + listSplit[j + 1].ToString());
                                    j++;
                                }
                            }
                            if (listvalue.Count % 4 != 0)
                            {
                                DevExpress.XtraEditors.XtraMessageBox.Show("错误！请检查导入setting文件");
                                break;
                            }
                            //转小端
                            for (int i = 0; i < listvalue.Count; i += 4)
                            {
                                var temp1 = listvalue[i];
                                var temp2 = listvalue[i + 1];
                                listvalue[i] = listvalue[i + 3];
                                listvalue[i + 1] = listvalue[i + 2];
                                listvalue[i + 3] = temp1;
                                listvalue[i + 2] = temp2;
                            }
                            addrCount = listvalue.Count / 8;
                            break;
                        case 1:
                            for (int i = 0; i < listR.Count(); i++)
                            {
                                var listSplit = fffevalue + string.Join("", listR[i].Split(','));

                                for (int j = 0; j < listSplit.Length; j++)
                                {
                                    listvalue.Add(listSplit[j].ToString() + listSplit[j + 1].ToString());
                                    j++;
                                }
                            }
                            if (listvalue.Count % 4 != 0)
                            {
                                DevExpress.XtraEditors.XtraMessageBox.Show("错误！请检查导入setting文件");
                                break;
                            }
                            for (int i = 0; i < listvalue.Count; i += 4)
                            {
                                var temp1 = listvalue[i];
                                listvalue[i] = listvalue[i + 2];
                                listvalue[i + 2] = temp1;
                            }
                            addrCount = listvalue.Count / 4;
                            break;
                        case 2:
                            for (int i = 0; i < listR.Count(); i++)
                            {
                                var listSplit = string.Join("", listR[i].Split(','));

                                for (int j = 0; j < listSplit.Length; j++)
                                {
                                    listvalue.Add(listSplit[j].ToString() + listSplit[j + 1].ToString());
                                    j++;
                                }
                            }
                            if (listvalue.Count % 2 != 0)
                            {
                                DevExpress.XtraEditors.XtraMessageBox.Show("错误！请检查导入setting文件");
                                break;
                            }
                            //转小端
                            //for (int i = 0; i < listvalue.Count; i += 4)
                            //{
                            //    var temp1 = listvalue[i];
                            //    var temp2 = listvalue[i + 1];
                            //    listvalue[i] = listvalue[i + 3];
                            //    listvalue[i + 1] = listvalue[i + 2];
                            //    listvalue[i + 3] = temp1;
                            //    listvalue[i + 2] = temp2;
                            //}
                            addrCount = listvalue.Count / 2;
                            break;
                        case 3:
                        case 4:
                            for (int i = 0; i < listR.Count(); i++)
                            {
                                var listSplit = listR[i].Split(',');
                                for (int y = 0; y < listSplit.Count(); y++)
                                {
                                    if (listSplit[y].Length < 4)
                                    {
                                        listSplit[y] = listSplit[y].PadLeft(4, '0');
                                    }
                                }
                                var StrSplit = string.Join("", listSplit);
                                for (int j = 0; j < StrSplit.Length; j++)
                                {
                                    listvalue.Add(StrSplit[j].ToString() + StrSplit[j + 1].ToString());
                                    j++;
                                }
                            }
                            if (listvalue.Count % 4 != 0)
                            {
                                DevExpress.XtraEditors.XtraMessageBox.Show("错误！请检查导入setting文件");
                                break;
                            }
                            //转小端
                            for (int i = 0; i < listvalue.Count; i += 4)
                            {
                                var temp1 = listvalue[i];
                                var temp2 = listvalue[i + 2];
                                listvalue[i] = listvalue[i + 1];
                                listvalue[i + 1] = temp1;
                                listvalue[i + 2] = listvalue[i + 3];
                                listvalue[i + 3] = temp2;
                            }
                            addrCount = listvalue.Count / 4;
                            break;
                        case 5:
                        case 6:
                            int listIndex = 1;
                            List<string> listRs = new List<string>();
                            listRs.AddRange(listR);
                            foreach (var item in listRs)
                            {
                                if (item.Contains("ffe1"))
                                {
                                    listR.Insert(listIndex,"ffe2,0000");
                                    listIndex++;
                                }
                                listIndex++;
                            }
                            for (int i = 0; i < listR.Count(); i++)
                            {
                                var listSplit = listR[i].Split(',')[1];
                                if (listSplit.Length < 4)
                                {
                                    listSplit = listSplit.PadLeft(4, '0');
                                }
                                for (int j = 0; j < listSplit.Length; j++)
                                {
                                    listvalue.Add(listSplit[j].ToString() + listSplit[j + 1].ToString());
                                    j++;
                                }

                            }
                            if (listvalue.Count % 4 != 0)
                            {
                                DevExpress.XtraEditors.XtraMessageBox.Show("错误！请检查导入setting文件");
                                break;
                            }
                            //转小端
                            for (int i = 0; i < listvalue.Count; i += 4)
                            {
                                var temp1 = listvalue[i];
                                var temp2 = listvalue[i + 1];
                                listvalue[i] = listvalue[i + 3];
                                listvalue[i + 1] = listvalue[i + 2];
                                listvalue[i + 3] = temp1;
                                listvalue[i + 2] = temp2;
                            }
                            addrCount = listvalue.Count / 8;
                            break;
                        case 7:
                            for (int i = 0; i < listR.Count(); i++)
                            {
                                var listSplit = listR[i].Split(',')[1];
                                if (listSplit.Length < 4)
                                {
                                    listSplit = listSplit.PadLeft(4, '0');
                                }
                                for (int j = 0; j < listSplit.Length; j++)
                                {
                                    listvalue.Add(listSplit[j].ToString()+listSplit[j+1].ToString());
                                    j++;
                                }

                            }
                            if (listvalue.Count % 4 != 0)
                            {
                                DevExpress.XtraEditors.XtraMessageBox.Show("错误！请检查导入setting文件");
                                break;
                            }
                            //转小端
                            for (int i = 0; i < listvalue.Count; i += 4)
                            {
                                var temp1 = listvalue[i];
                                var temp2 = listvalue[i + 1];
                                listvalue[i] = listvalue[i + 3];
                                listvalue[i + 1] = listvalue[i + 2];
                                listvalue[i + 3] = temp1;
                                listvalue[i + 2] = temp2;
                            }
                            addrCount = listvalue.Count / 8;
                            break;
                        default:
                            break;
                    }
                    SerialSend.WriteRegister(0x20000058, Convert.ToUInt32(addrCount), sPortTemp);
                    listRecording.Add($"0x20000058,0x{Convert.ToUInt32(addrCount).ToString("X2")}");
                    for (int i = 0; i < listvalue.Count(); i++)
                    {
                        listRecording.Add("0x" + (Convert.ToUInt32(sensor_reg.Text, 16) + i).ToString("X2")+","+"0x"+ listvalue[i]);
                        SerialSend.WriteRegister((ulong)(Convert.ToUInt32(sensor_reg.Text, 16) + i), Convert.ToUInt32(listvalue[i],16), sPortTemp);
                    }
                    var filePath = $"{ Application.StartupPath}\\Lib\\xc151_setting\\GroupWrite.txt";
                    using (StreamWriter writer = new StreamWriter(filePath))
                    {
                        // 遍历 List，将每个字符串写入 .txt 文件中
                        foreach (string data in listRecording)
                        {
                            writer.WriteLine(data);
                        }
                    }
                    Application.DoEvents();
                    WaitBefore.Close();
                    SerialSend.isDebug = true;
                    DevExpress.XtraEditors.XtraMessageBox.Show("完成");
                    //MessageBox.Show("完成");
                }

                catch (Exception ex)
                {
                    WaitBefore.Close();
                    SerialSend.isDebug = true;
                    DevExpress.XtraEditors.XtraMessageBox.Show(ex.Message);
                    //MessageBox.Show(ex.Message);
                }
            }
        }
        public static List<string> Regex16ToString(string reg)
        {
            var strlist = new List<string>();
            Regex ConnoteA = new Regex("(0x)[a-fA-F0-9]{1,4}");
            foreach (var item in ConnoteA.Matches(reg))
            {
                strlist.Add(item.ToString().Replace("0x", "").Replace(" ", "").ToLower());
            }
            return strlist;
        }
        public static List<string> ReadTextFileToList(string fileName)
        {
            List<string> list = new List<string>();

            FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);

            StreamReader sr = new StreamReader(fs);
            //使用StreamReader类来读取文件 
            sr.BaseStream.Seek(0, SeekOrigin.Begin);
            // 从数据流中读取每一行，直到文件的最后一行
            string tmp = sr.ReadLine();
            while (tmp != null)
            {
                list.Add(tmp);
                tmp = sr.ReadLine();
            }
            //关闭此StreamReader对象 
            sr.Close();
            fs.Close();
            return list;
        }

    }
}